<template>
  <div class="broadcast-shout-page">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2 class="page-title">
        <el-icon><Microphone /></el-icon>
        广播喊话
      </h2>
      <p class="page-description">选择设备进行实时广播喊话</p>
    </div>

    <!-- 设备选择卡片 -->
    <div class="device-selection-card">
      <div class="card-header">
        <h3 class="section-title">
          <el-icon><Microphone /></el-icon>
          播放设备
        </h3>
        <el-button type="primary" @click="openDeviceDialog">
          <el-icon><Plus /></el-icon>
          选择设备
        </el-button>
      </div>

      <!-- 已选择设备显示 -->
      <div v-if="selectedDevices.length === 0" class="empty-device">
        <el-empty
          description="暂未选择设备，请点击上方按钮选择设备"
          :image-size="100"
        />
      </div>
      <div v-else class="selected-devices-list">
        <el-tag
          v-for="device in getSelectedDevicesInfo()"
          :key="device.id"
          type="primary"
          size="large"
          closable
          @close="removeDevice(device.id)"
          class="device-tag"
        >
          <div class="tag-content">
            <span class="device-name">{{ device.name }}</span>
            <span class="device-id">ID: {{ device.id }}</span>
          </div>
        </el-tag>
      </div>
    </div>

    <!-- 设备选择弹窗 -->
    <el-dialog
      v-model="showDeviceDialog"
      title="选择播放设备"
      width="70%"
      :close-on-click-modal="false"
      :center="true"
      :append-to-body="true"
      class="device-dialog"
    >
      <!-- 层级筛选器 -->
      <div class="hierarchical-filters">
        <h3 class="section-title">
          <el-icon><Filter /></el-icon>
          筛选条件
        </h3>

        <div class="filter-container">
          <div class="filter-item">
            <label>大区：</label>
            <el-select
              v-model="filters.regionId"
              placeholder="请选择大区"
              @change="handleRegionChange"
              clearable
            >
              <el-option
                v-for="region in regionList"
                :key="region.id"
                :label="region.name"
                :value="region.id"
              />
            </el-select>
          </div>

          <div class="filter-item">
            <label>项目：</label>
            <el-select
              v-model="filters.projectId"
              placeholder="请选择项目"
              @change="handleProjectChange"
              clearable
              :disabled="!filters.regionId"
            >
              <el-option
                v-for="project in projectList"
                :key="project.id"
                :label="project.name"
                :value="project.id"
              />
            </el-select>
          </div>

          <div class="filter-item">
            <label>工区：</label>
            <el-select
              v-model="filters.workAreaId"
              placeholder="请选择工区"
              @change="handleWorkAreaChange"
              clearable
              :disabled="!filters.projectId"
            >
              <el-option
                v-for="workArea in workAreaList"
                :key="workArea.id"
                :label="workArea.name"
                :value="workArea.id"
              />
            </el-select>
          </div>

          <div class="filter-item">
            <label>站点：</label>
            <el-select
              v-model="filters.stationId"
              placeholder="请选择站点"
              @change="handleStationChange"
              clearable
              :disabled="!filters.workAreaId"
            >
              <el-option
                v-for="station in stationList"
                :key="station.id"
                :label="station.name"
                :value="station.id"
              />
            </el-select>
          </div>

          <div class="filter-item">
            <label>装置：</label>
            <el-select
              v-model="filters.deviceId"
              placeholder="请选择装置"
              @change="handleDeviceChange"
              clearable
              :disabled="!filters.stationId"
            >
              <el-option
                v-for="rod in rodList"
                :key="rod.id"
                :label="rod.name"
                :value="rod.id"
              />
            </el-select>
          </div>

          <div class="filter-item filter-action">
            <el-button type="primary" @click="searchDevices" :loading="loading">
              <el-icon><Search /></el-icon>
              搜索设备
            </el-button>
            <el-button @click="resetFilters">
              <el-icon><RefreshLeft /></el-icon>
              重置
            </el-button>
          </div>
        </div>
      </div>

      <!-- 设备选择区域 -->
      <div class="device-selection">
        <div class="device-header">
          <h3 class="section-title">
            <el-icon><Microphone /></el-icon>
            选择播放设备
          </h3>

          <div class="device-actions">
            <el-button
              :type="isAllSelected ? 'default' : 'primary'"
              size="small"
              @click="toggleSelectAll"
              :disabled="deviceList.length === 0"
            >
              <el-icon v-if="isAllSelected"><Close /></el-icon>
              <el-icon v-else><Check /></el-icon>
              {{ isAllSelected ? "取消全选" : "全选" }}
            </el-button>
          </div>
        </div>

        <div class="device-list" v-loading="loading">
          <div v-if="deviceList.length === 0" class="empty-state">
            <el-empty description="暂无设备数据，请先选择筛选条件" />
          </div>

          <div v-else class="device-cards">
            <div
              v-for="device in deviceList"
              :key="device.id"
              class="device-card"
              :class="{
                offline: device.status === 'offline',
                selected: tempSelectedDevices.includes(device.id),
              }"
              @click="toggleTempDeviceSelection(device.id)"
            >
              <div class="card-header">
                <el-checkbox
                  :model-value="tempSelectedDevices.includes(device.id)"
                  :disabled="device.status === 'offline'"
                  @change="toggleTempDeviceSelection(device.id)"
                  @click.stop
                />
                <div class="device-id">设备ID: {{ device.id }}</div>
              </div>

              <div class="card-content">
                <div class="device-name">{{ device.name }}</div>
                <div class="device-info">
                  <div class="info-item" v-if="device.zoneName">
                    <span class="label">大区：</span>
                    <span class="value">{{ device.zoneName }}</span>
                  </div>
                  <div class="info-item" v-if="device.projectName">
                    <span class="label">项目：</span>
                    <span class="value">{{ device.projectName }}</span>
                  </div>
                  <div class="info-item" v-if="device.areaName">
                    <span class="label">工区：</span>
                    <span class="value">{{ device.areaName }}</span>
                  </div>
                  <div class="info-item" v-if="device.stationName">
                    <span class="label">站点：</span>
                    <span class="value">{{ device.stationName }}</span>
                  </div>
                  <div class="info-item" v-if="device.rodName">
                    <span class="label">装置：</span>
                    <span class="value">{{ device.rodName }}</span>
                  </div>
                </div>
              </div>

              <div class="card-footer">
                <el-tag
                  :type="device.status === 'online' ? 'success' : 'danger'"
                  size="small"
                >
                  {{ device.status === "online" ? "在线" : "离线" }}
                </el-tag>
              </div>
            </div>
          </div>
        </div>

        <!-- 临时选中设备显示 -->
        <div
          v-if="tempSelectedDevices.length > 0"
          class="temp-selected-devices"
        >
          <h4>当前已选择 {{ tempSelectedDevices.length }} 个设备</h4>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelDeviceSelection">取消</el-button>
          <el-button type="primary" @click="confirmDeviceSelection">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 对讲控制区域 -->
    <div class="call-control" v-if="callStatus.isConnected">
      <h3 class="section-title">
        <el-icon><Headset /></el-icon>
        实时对讲
      </h3>

      <div class="control-buttons">
        <el-button
          type="success"
          size="large"
          :loading="callStatus.loading"
          :disabled="callStatus.isSpeaking"
          @click="startSpeaking"
          class="control-btn"
        >
          <el-icon><Microphone /></el-icon>
          {{ callStatus.isSpeaking ? "正在说话..." : "开始说话" }}
        </el-button>

        <el-button
          type="danger"
          size="large"
          :disabled="!callStatus.isSpeaking"
          @click="stopSpeaking"
          class="control-btn"
        >
          <el-icon><Mute /></el-icon>
          停止说话
        </el-button>
      </div>

      <div class="call-status">
        <el-tag :type="callStatus.isSpeaking ? 'success' : 'info'" size="large">
          {{ callStatus.isSpeaking ? "正在对讲中..." : "等待开始对讲" }}
        </el-tag>
      </div>
    </div>

    <!-- 喊话操作按钮 -->
    <div class="action-buttons">
      <el-button
        type="primary"
        size="large"
        :loading="wsConnection.connecting"
        :disabled="selectedDevices.length === 0 || callStatus.isConnected"
        @click="startShout"
        class="action-btn"
      >
        <el-icon><VideoPlay /></el-icon>
        创建连接
      </el-button>

      <el-button
        type="danger"
        size="large"
        :disabled="!callStatus.isConnected"
        @click="stopShout"
        class="action-btn"
      >
        <el-icon><VideoPause /></el-icon>
        断开连接
      </el-button>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ElMessage, ElLoading } from "element-plus";
import {
  Microphone,
  Mute,
  VideoPlay,
  VideoPause,
  Headset,
  Check,
  Loading,
  Filter,
  Search,
  Close,
  RefreshLeft,
  Plus,
} from "@element-plus/icons-vue";
import { ResultCode } from "@/utils/ResultCode.ts";
import {
  tree,
  getUserAuth,
  getBroadcastServerList,
  getConnectionParams,
  createBroadcastRecord,
  type TreeNode,
  type BroadcastDevice,
  type ConnectionParams,
  type BroadcastServer,
} from "../../api/rdAlarmSpeak";
import CryptoJS from "crypto-js";

defineOptions({ name: "alarm:rdAlarmSpeak" });

// AES解密函数（匹配后端 AES-256-CBC 模式）
const decryptPassword = (
  encryptedPassword: string,
  encryptionKey: string = "abcdefghijklmnop"
): string => {
  try {
    // 1. Base64解码得到原始字节数据（IV + 密文）
    const encryptedBytes = CryptoJS.enc.Base64.parse(encryptedPassword);

    // 2. AES-256-CBC 的 IV 长度固定为 16 字节
    const ivLength = 16;

    // 3. 提取 IV（前16字节）
    const ivWords: number[] = [];
    for (let i = 0; i < ivLength / 4; i++) {
      ivWords.push(encryptedBytes.words[i]);
    }
    const iv = CryptoJS.lib.WordArray.create(ivWords, ivLength);

    // 4. 提取加密数据（从第16字节开始到结尾）
    const encryptedWords: number[] = [];
    const encryptedLength = encryptedBytes.sigBytes - ivLength;
    for (let i = ivLength / 4; i < encryptedBytes.words.length; i++) {
      encryptedWords.push(encryptedBytes.words[i]);
    }
    const encrypted = CryptoJS.lib.WordArray.create(
      encryptedWords,
      encryptedLength
    );

    // 5. 准备密钥
    // AES-256 需要32字节密钥，如果密钥不足32字节，需要填充
    let key = CryptoJS.enc.Utf8.parse(encryptionKey);
    if (key.sigBytes < 32) {
      // 如果密钥不足32字节，用0填充到32字节
      const paddedKey = CryptoJS.lib.WordArray.create();
      paddedKey.concat(key);
      // 补充0到32字节
      const zerosNeeded = 32 - key.sigBytes;
      const zeros = CryptoJS.lib.WordArray.create(
        new Array(zerosNeeded / 4).fill(0),
        zerosNeeded
      );
      paddedKey.concat(zeros);
      key = paddedKey;
    }

    // 6. 执行解密（使用 CBC 模式，PKCS7填充）
    const decrypted = CryptoJS.AES.decrypt(
      CryptoJS.lib.CipherParams.create({
        ciphertext: encrypted,
      }),
      key,
      {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7,
      }
    );

    const result = decrypted.toString(CryptoJS.enc.Utf8);

    if (!result) {
      console.error("密码解密失败：解密结果为空");
      return encryptedPassword;
    }

    return result;
  } catch (error) {
    console.error("密码解密失败:", error);
    return encryptedPassword; // 解密失败时返回原密码
  }
};

// 动态加载JS文件
const loadScript = (src: string): Promise<void> => {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.src = src;
    script.onload = () => {
      // console.log(`脚本加载成功: ${src}`);
      resolve();
    };
    script.onerror = (error) => {
      console.error(`脚本加载失败: ${src}`, error);
      reject(error);
    };
    document.head.appendChild(script);
  });
};

// Parrot客户端相关变量
let parrotApi: any = null;
let parrotClient: any = null;
let pcmPlayer: any = null;
let pcmRecorder: any = null;

// 定义接口类型
interface BaseItem {
  id: number;
  name: string;
}

// 设备项
interface DeviceItem {
  id: number; // 系统中的设备ID
  deviceId: number; // 喊话时使用的设备ID
  name: string;
  status: "online" | "offline";
  serverId: number; // 服务器ID
  rodName?: string; // 装置名称
  stationName?: string; // 站点名称
  areaName?: string; // 工区名称
  projectName?: string; // 项目名称
  zoneName?: string; // 大区名称
}

// 筛选条件
const filters = ref({
  regionId: null as number | null,
  projectId: null as number | null,
  workAreaId: null as number | null,
  stationId: null as number | null,
  deviceId: null as number | null,
});

// 树形数据
const treeData = ref<TreeNode[]>([]);

// 层级数据列表
const regionList = ref<BaseItem[]>([]);
const projectList = ref<BaseItem[]>([]);
const workAreaList = ref<BaseItem[]>([]);
const stationList = ref<BaseItem[]>([]);
const rodList = ref<BaseItem[]>([]);

// 设备列表
const deviceList = ref<DeviceItem[]>([]);

// 选中的设备
const selectedDevices = ref<number[]>([]);

// 弹窗中临时选中的设备
const tempSelectedDevices = ref<number[]>([]);

// 弹窗显示控制
const showDeviceDialog = ref(false);

// 计算是否全选
const isAllSelected = computed(() => {
  if (deviceList.value.length === 0) return false;
  const onlineDevices = deviceList.value.filter((d) => d.status === "online");
  return (
    onlineDevices.length > 0 &&
    tempSelectedDevices.value.length === onlineDevices.length
  );
});

// WebSocket连接状态
const wsConnection = ref({
  connected: false, // 连接状态
  connecting: false, // 连接中状态
  user: "",
  password: "",
  wsUrl: "",
  retryCount: 0, // 重试次数
  maxRetries: 5, // 最大重试次数
});

// 连接参数
const connectionParams = ref<ConnectionParams | null>(null);

// 广播服务器信息
const broadcastServer = ref<BroadcastServer | null>(null);

// 多服务器连接管理
interface ServerConnection {
  server: BroadcastServer;
  connected: boolean;
  connecting: boolean;
  parrotClient: any;
  pcmPlayer: any;
  connectionParams: ConnectionParams;
  devices: number[]; // 该服务器下的设备ID列表
  retryCount: number; // 重连次数
  maxRetries: number; // 最大重连次数
  lastRetryTime: number; // 最后重连时间
  connectionFailed: boolean; // 连接是否失败
}

const serverConnections = ref<Map<number, ServerConnection>>(new Map());

// 全局共享的录音器
let sharedPcmRecorder: any = null;

// 对讲状态
const callStatus = ref({
  isSpeaking: false,
  isConnected: false,
  loading: false,
  deviceStatus: {} as Record<number, boolean>, // 设备连接状态
  serverStatus: {} as Record<number, boolean>, // 服务器连接状态
  speakStartTime: null as number | null, // 开始说话的时间戳（秒）
});

// 加载状态
const loading = ref(false);

// 从树中收集所有广播设备
const collectAllDevices = (
  nodes: TreeNode[],
  pathInfo: any = {}
): DeviceItem[] => {
  let devices: DeviceItem[] = [];

  for (const node of nodes) {
    const currentPath = { ...pathInfo };

    // 记录路径信息
    if (node.type === "zone") {
      currentPath.zoneName = node.name;
    } else if (node.type === "proj_line") {
      currentPath.projectName = node.name;
    } else if (node.type === "area") {
      currentPath.areaName = node.name;
    } else if (node.type === "stand") {
      currentPath.stationName = node.name;
    } else if (node.type === "rod") {
      currentPath.rodName = node.name;

      // 收集该装置下的广播设备
      if (node.broadcast && node.broadcast.length > 0) {
        const rodDevices = node.broadcast.map((b) => ({
          id: b.id,
          deviceId: b.device_id, // 喊话时使用的设备ID
          name: b.name,
          status: (b.status === 1 ? "online" : "offline") as "online" | "offline",
          serverId: b.server_id,
          ...currentPath,
        }));
        devices.push(...rodDevices);
      }
    }

    // 递归处理子节点
    if (node.children && node.children.length > 0) {
      devices.push(...collectAllDevices(node.children, currentPath));
    }
  }

  return devices;
};

// 根据筛选条件过滤设备
const filterDevicesByConditions = () => {

  if (treeData.value.length === 0) {
    return [];
  }

  let filteredNodes = treeData.value;

  // 按大区筛选
  if (filters.value.regionId) {
    filteredNodes = filteredNodes.filter(
      (n) => n.id === filters.value.regionId
    );
  }

  // 按项目筛选
  if (filters.value.projectId && filteredNodes.length > 0) {
    const projects = filteredNodes.flatMap((n) => n.children || []);
    filteredNodes = [
      {
        ...filteredNodes[0],
        children: projects.filter((p) => p.id === filters.value.projectId),
      },
    ];
  }

  // 按工区筛选
  if (
    filters.value.workAreaId &&
    filteredNodes.length > 0 &&
    filteredNodes[0].children
  ) {
    const areas = filteredNodes[0].children.flatMap((n) => n.children || []);
    filteredNodes = [
      {
        ...filteredNodes[0],
        children: [
          {
            ...filteredNodes[0].children[0],
            children: areas.filter((a) => a.id === filters.value.workAreaId),
          },
        ],
      },
    ];
  }

  // 按站点筛选 - 保留完整路径信息
  if (filters.value.stationId && filteredNodes.length > 0) {
    const findStationWithPath = (
      nodes: TreeNode[],
      path: TreeNode[] = []
    ): TreeNode[] | null => {
      for (const node of nodes) {
        const currentPath = [...path, node];

        if (node.type === "stand" && node.id === filters.value.stationId) {
          // 找到目标站点，重建包含完整路径的树结构
          let result = node;
          for (let i = currentPath.length - 2; i >= 0; i--) {
            const parent = currentPath[i];
            result = {
              ...parent,
              children: [result],
            };
          }
          return [result];
        }

        if (node.children) {
          const found = findStationWithPath(node.children, currentPath);
          if (found) return found;
        }
      }
      return null;
    };

    const result = findStationWithPath(filteredNodes);
    if (result) {
      filteredNodes = result;
    }
  }

  // 按装置筛选 - 保留完整路径信息
  if (filters.value.deviceId && filteredNodes.length > 0) {
    const findRodWithPath = (
      nodes: TreeNode[],
      path: TreeNode[] = []
    ): TreeNode[] | null => {
      for (const node of nodes) {
        const currentPath = [...path, node];

        if (node.type === "rod" && node.id === filters.value.deviceId) {
          // 找到目标装置，重建包含完整路径的树结构
          let result = node;
          for (let i = currentPath.length - 2; i >= 0; i--) {
            const parent = currentPath[i];
            result = {
              ...parent,
              children: [result],
            };
          }
          return [result];
        }

        if (node.children) {
          const found = findRodWithPath(node.children, currentPath);
          if (found) return found;
        }
      }
      return null;
    };

    const result = findRodWithPath(filteredNodes);
    if (result) {
      filteredNodes = result;
    }
  }

  // 收集所有广播设备（从 broadcast 数组中）
  return collectAllDevices(filteredNodes);
};

// 层级筛选处理函数
const handleRegionChange = async (regionId: number) => {
  filters.value.projectId = null;
  filters.value.workAreaId = null;
  filters.value.stationId = null;
  filters.value.deviceId = null;
  projectList.value = [];
  workAreaList.value = [];
  stationList.value = [];
  rodList.value = [];

  if (regionId) {
    const region = treeData.value.find((r) => r.id === regionId);
    if (region && region.children) {
      projectList.value = region.children.map((p) => ({
        id: p.id,
        name: p.name,
      }));
    }
  }
};

const handleProjectChange = async (projectId: number) => {
  filters.value.workAreaId = null;
  filters.value.stationId = null;
  filters.value.deviceId = null;
  workAreaList.value = [];
  stationList.value = [];
  rodList.value = [];

  if (projectId && filters.value.regionId) {
    const region = treeData.value.find((r) => r.id === filters.value.regionId);
    const project = region?.children?.find((p) => p.id === projectId);
    if (project && project.children) {
      workAreaList.value = project.children.map((a) => ({
        id: a.id,
        name: a.name,
      }));
    }
  }
};

const handleWorkAreaChange = async (workAreaId: number) => {
  filters.value.stationId = null;
  filters.value.deviceId = null;
  stationList.value = [];
  rodList.value = [];

  if (workAreaId && filters.value.regionId && filters.value.projectId) {
    const region = treeData.value.find((r) => r.id === filters.value.regionId);
    const project = region?.children?.find(
      (p) => p.id === filters.value.projectId
    );
    const area = project?.children?.find((a) => a.id === workAreaId);
    if (area && area.children) {
      stationList.value = area.children.map((s) => ({
        id: s.id,
        name: s.name,
      }));
    }
  }
};

const handleStationChange = async (stationId: number) => {
  filters.value.deviceId = null;
  rodList.value = [];

  if (stationId) {
    // 从树中找到对应站点
    const findStation = (nodes: TreeNode[]): TreeNode | undefined => {
      for (const node of nodes) {
        if (node.type === "stand" && node.id === stationId) {
          return node;
        }
        if (node.children) {
          const found = findStation(node.children);
          if (found) return found;
        }
      }
      return undefined;
    };

    const station = findStation(treeData.value);
    // 只收集 type 为 'rod' 的装置节点
    if (station && station.children) {
      rodList.value = station.children
        .filter((node) => node.type === "rod")
        .map((r) => ({ id: r.id, name: r.name }));
    }
  }
};

const handleDeviceChange = async (deviceId: number) => {
  // 装置选择后的处理
};

// 重置筛选条件
const resetFilters = () => {
  filters.value = {
    regionId: null,
    projectId: null,
    workAreaId: null,
    stationId: null,
    deviceId: null,
  };

  projectList.value = [];
  workAreaList.value = [];
  stationList.value = [];
  rodList.value = [];

  // 重新加载所有设备
  deviceList.value = collectAllDevices(treeData.value);
  selectedDevices.value = [];

  ElMessage.success("已重置筛选条件");
};

// 搜索设备
const searchDevices = async () => {
  loading.value = true;
  try {
    // 根据筛选条件过滤设备
    deviceList.value = filterDevicesByConditions();

    if (deviceList.value.length === 0) {
      ElMessage.warning("未找到符合条件的设备");
    } else {
      ElMessage.success(`找到 ${deviceList.value.length} 台设备`);
    }
  } catch (error) {
    console.error("搜索设备失败:", error);
    ElMessage.error("获取设备列表失败");
  } finally {
    loading.value = false;
  }
};

// 设备选择处理
const toggleDeviceSelection = (deviceId: number) => {
  const index = selectedDevices.value.indexOf(deviceId);
  if (index > -1) {
    selectedDevices.value.splice(index, 1);
  } else {
    selectedDevices.value.push(deviceId);
  }
};

// 切换设备选择状态（弹窗内临时选择）
const toggleTempDeviceSelection = (deviceId: number) => {
  const index = tempSelectedDevices.value.indexOf(deviceId);
  if (index > -1) {
    tempSelectedDevices.value.splice(index, 1);
  } else {
    tempSelectedDevices.value.push(deviceId);
  }
};

// 切换全选/取消全选
const toggleSelectAll = () => {
  if (isAllSelected.value) {
    // 当前是全选状态，则取消全选
    tempSelectedDevices.value = [];
  } else {
    // 当前未全选，则全选所有在线设备
    tempSelectedDevices.value = deviceList.value
      .filter((device) => device.status === "online")
      .map((device) => device.id);
  }
};

// 确认设备选择
const confirmDeviceSelection = () => {
  selectedDevices.value = [...tempSelectedDevices.value];
  showDeviceDialog.value = false;
  ElMessage.success(`已选择 ${selectedDevices.value.length} 个设备`);

  // 如果已连接，更新设备目标
  if (wsConnection.value.connected) {
    updateDeviceTargets();
  }
};

// 取消设备选择
const cancelDeviceSelection = () => {
  tempSelectedDevices.value = [...selectedDevices.value];
  showDeviceDialog.value = false;
};

// 移除设备
const removeDevice = (deviceId: number) => {
  const index = selectedDevices.value.indexOf(deviceId);
  if (index > -1) {
    selectedDevices.value.splice(index, 1);
  }

  // 如果已连接且还有设备，更新设备目标
  if (wsConnection.value.connected && selectedDevices.value.length > 0) {
    updateDeviceTargets();
  }
};

// 获取选中设备的详细信息
const getSelectedDevicesInfo = () => {
  return deviceList.value.filter((device) =>
    selectedDevices.value.includes(device.id)
  );
};

// 初始化单个服务器的Parrot客户端
const initServerParrotClient = async (serverId: number, serverInfo: BroadcastServer, deviceIds: number[]) => {
  if (!parrotApi) {
    ElMessage.error("Parrot API 未初始化");
    return null;
  }

  try {
    // 为每个服务器创建独立的 ParrotApi 实例
    console.log(`为服务器${serverId}创建独立的 ParrotApi 实例`);
    const serverParrotApi = await (window as any).ParrotApi();
    
    if (!serverParrotApi) {
      throw new Error(`服务器${serverId}的 ParrotApi 初始化失败`);
    }
    
    // 创建播放器
    const player = new (window as any).PCMPlayer({
      inputCodec: "Int16",
      channels: 1,
      sampleRate: 8000,
      flushTime: 320,
    });

    // 使用独立的 ParrotApi 实例创建客户端
    const client = new (window as any).ParrotClient(serverParrotApi);

    // 监听播放帧
    client.on("playFrame", function (event: string, data: Uint8Array) {
      const view = new DataView(data.buffer);
      const buf = new Int16Array(data.byteLength / 2);

      for (let i = 0; i < data.byteLength / 2; i++) {
        buf[i] = view.getInt16(2 * i, true);
      }

      player.feed(buf);
    });

    // 监听喊话状态
    client.on("liveCastingStatus", function (event: string, data: any) {
      callStatus.value.isSpeaking = data.casting;

      // 处理设备连接状态
      if (data.devices) {
        Object.keys(data.devices).forEach((deviceId) => {
          const id = parseInt(deviceId);
          callStatus.value.deviceStatus[id] =
            data.devices[deviceId].connected;
        });
      }
    });

    // 监听登录状态
    client.on("loginStatus", function (event: string, data: any) {
      // status: 1-连接中, 2-已连接但未登录, 3-已登录(在线),4-设备已连接，请勿重复连接, 0-断开
      console.log(`服务器${serverId}登录状态:`, data);

      const conn = serverConnections.value.get(serverId);
      if (!conn) return;

      if (data.status === 3) {
        // 登录成功
        conn.connected = true;
        conn.connecting = false;
        conn.connectionFailed = false;
        conn.retryCount = 0; // 重置重连次数
        callStatus.value.serverStatus[serverId] = true;
        // ElMessage.success(`服务器${serverId}连接成功`);
      } else if (data.status === 4) {
        // 设备已被其他人连接
        conn.connected = false;
        conn.connecting = false;
        conn.connectionFailed = true; // 标记为连接失败，不再重连
        callStatus.value.serverStatus[serverId] = false;
        ElMessage.error(`服务器${serverId}设备已被连接`);
      } else if (data.status === 1) {
        // 连接中
        conn.connecting = true;
      } else if (data.status === 0) {
        // 连接失败
        conn.connected = false;
        conn.connecting = false;
        callStatus.value.serverStatus[serverId] = false;
        
        // 检查是否需要重连
        if (conn.retryCount < conn.maxRetries) {
          // 延迟重连
          setTimeout(() => {
            retryServerConnection(serverId);
          }, 2000 * (conn.retryCount + 1)); // 递增延迟
        } else {
          // 达到最大重连次数，断开连接
          conn.connectionFailed = true;
          disconnectServer(serverId);
          ElMessage.error(`服务器${conn.server.name}连接失败，已达到最大重连次数(${conn.maxRetries}次)，连接已断开`);
        }
      }

      // 更新总体连接状态
      updateOverallConnectionStatus();
    });

    // 使用全局共享的录音器
    if (!sharedPcmRecorder) {
      sharedPcmRecorder = new (window as any).PcmRecorder();
      await sharedPcmRecorder.requestMicrophone();

      // 等待麦克风准备就绪
      await new Promise<void>((resolve, reject) => {
        const checkReady = setInterval(() => {
          if (sharedPcmRecorder.ready) {
            clearInterval(checkReady);
            resolve();
          }
        }, 100);

        // 5秒超时
        setTimeout(() => {
          clearInterval(checkReady);
          if (!sharedPcmRecorder.ready) {
            reject(new Error("麦克风初始化超时"));
          }
        }, 5000);
      });
    }

    // 为当前客户端绑定录音器事件
    const sendFrameHandler = client.sendFrame.bind(client);
    const startRecordHandler = () => {
      // 只在第一次开始录音时调用
      if (!sharedPcmRecorder.isRecording) {
        sharedPcmRecorder.startRecord();
      }
    };
    const stopRecordHandler = () => {
      // 检查是否还有其他服务器在喊话
      const anyOtherSpeaking = Array.from(serverConnections.value.values()).some(
        conn => conn.parrotClient !== client && conn.parrotClient?.isCasting
      );
      if (!anyOtherSpeaking) {
        sharedPcmRecorder.stopRecord();
      }
    };

    // 将此客户端的sendFrame添加到录音器的回调列表
    if (!sharedPcmRecorder.frameCallbacks) {
      sharedPcmRecorder.frameCallbacks = [];
      sharedPcmRecorder.onFrameData = (data: any) => {
        sharedPcmRecorder.frameCallbacks.forEach((cb: any) => cb(data));
      };
    }
    
    // 添加回调到列表
    sharedPcmRecorder.frameCallbacks.push(sendFrameHandler);
    
    // 如果录音器已经在录音中，说明有其他客户端已经开启了录音
    // 需要立即触发这个客户端的startRecord，让它也开始发送音频
    if (sharedPcmRecorder.isRecording) {
      console.log(`录音器已在运行中，立即为客户端${serverId}启动音频发送`);
      setTimeout(() => {
        startRecordHandler();
      }, 0);
    }

    client.on("startRecord", startRecordHandler);
    client.on("stopRecord", stopRecordHandler);

    // 解密密码
    const decryptedPassword = decryptPassword(serverInfo.password);

    // 从 link 中提取 WebSocket URL
    let wsUrl = serverInfo.link;
    if (wsUrl.startsWith('http://')) {
      wsUrl = wsUrl.replace('http://', 'ws://');
    } else if (wsUrl.startsWith('https://')) {
      wsUrl = wsUrl.replace('https://', 'wss://');
    }
    wsUrl = `${wsUrl}/v1/ws/client`;

    // 构建连接参数
    const connParams: ConnectionParams = {
      ws_url: wsUrl,
      user: serverInfo.username,
      pwd: decryptedPassword,
    };

    return {
      parrotClient: client,
      pcmPlayer: player,
      connectionParams: connParams,
    };
  } catch (error) {
    console.error(`初始化服务器${serverId}的Parrot客户端失败:`, error);
    throw error;
  }
};

// 更新总体连接状态
const updateOverallConnectionStatus = () => {
  const connections = Array.from(serverConnections.value.values());
  const anyConnected = connections.some(conn => conn.connected);
  const anyConnecting = connections.some(conn => conn.connecting);

  callStatus.value.isConnected = anyConnected;
  wsConnection.value.connected = anyConnected;
  wsConnection.value.connecting = anyConnecting && !anyConnected;
};

// 重连服务器
const retryServerConnection = async (serverId: number) => {
  const conn = serverConnections.value.get(serverId);
  if (!conn || conn.connectionFailed) return;

  conn.retryCount++;
  conn.lastRetryTime = Date.now();
  
  console.log(`服务器${serverId}第${conn.retryCount}次重连尝试`);
  
  try {
    // 重新建立WebSocket连接
    await connectServerWebSocket(serverId);
  } catch (error) {
    console.error(`服务器${serverId}重连失败:`, error);
    if (conn.retryCount >= conn.maxRetries) {
      conn.connectionFailed = true;
      disconnectServer(serverId);
      ElMessage.error(`服务器${conn.server.name}重连失败，已达到最大重连次数，连接已断开`);
    }
  }
};

// 断开服务器连接
const disconnectServer = (serverId: number) => {
  const conn = serverConnections.value.get(serverId);
  if (!conn) return;

  // 断开WebSocket连接
  if (conn.parrotClient) {
    conn.parrotClient.disconnect();
    console.log(`服务器${serverId}连接已断开`);
  }

  // 更新连接状态
  conn.connected = false;
  conn.connecting = false;
  conn.connectionFailed = true;
  callStatus.value.serverStatus[serverId] = false;

  // 更新总体连接状态
  updateOverallConnectionStatus();
};

// 初始化Parrot客户端(保留旧版本以兼容)
const initParrotClient = async () => {
  if (!parrotApi) {
    ElMessage.error("Parrot API 未初始化");
    return false;
  }

  try {
    // 创建播放器
    if (!pcmPlayer) {
      pcmPlayer = new (window as any).PCMPlayer({
        inputCodec: "Int16",
        channels: 1,
        sampleRate: 8000,
        flushTime: 320,
      });
    }

    // 创建客户端
    if (!parrotClient) {
      parrotClient = new (window as any).ParrotClient(parrotApi);

      // 监听播放帧
      parrotClient.on("playFrame", function (event: string, data: Uint8Array) {
        const view = new DataView(data.buffer);
        const buf = new Int16Array(data.byteLength / 2);

        for (let i = 0; i < data.byteLength / 2; i++) {
          buf[i] = view.getInt16(2 * i, true);
        }

        pcmPlayer.feed(buf);
      });

      // 监听喊话状态
      parrotClient.on("liveCastingStatus", function (event: string, data: any) {
        callStatus.value.isSpeaking = data.casting;

        // 处理设备连接状态
        if (data.devices) {
          Object.keys(data.devices).forEach((deviceId) => {
            const id = parseInt(deviceId);
            callStatus.value.deviceStatus[id] =
              data.devices[deviceId].connected;
          });
        }
      });

      // 监听登录状态
      parrotClient.on("loginStatus", function (event: string, data: any) {
        // status: 1-连接中, 2-已连接但未登录, 3-已登录(在线),4-设备已连接，请勿重复连接, 0-断开
        console.log(77777,data);

        if (data.status === 3) {
          // 登录成功，重置重试次数
          wsConnection.value.connected = true;
          wsConnection.value.connecting = false;
          wsConnection.value.retryCount = 0;
          callStatus.value.isConnected = true;
          ElMessage.success("设备连接成功");
        } else if (data.status === 4) {
          // 设备已被其他人连接，无法重复连接
          wsConnection.value.connected = false;
          wsConnection.value.connecting = false;
          callStatus.value.isConnected = false;
          ElMessage.error("设备已被连接，请勿重复连接");
        } else if (data.status === 1) {
          // 连接中
          wsConnection.value.connecting = true;
          ElMessage.info("正在连接设备...");
        } else if (data.status === 2) {
          // 已连接但未登录
          ElMessage.info("设备已连接，正在登录...");
        } else if (data.status === 0) {
          // 连接失败
          wsConnection.value.connected = false;
          wsConnection.value.connecting = false;
          callStatus.value.isConnected = false;

          // 增加重试次数
          wsConnection.value.retryCount++;

          if (wsConnection.value.retryCount >= wsConnection.value.maxRetries) {
            // 达到最大重试次数
            ElMessage.error({
              message: `连接失败已达${wsConnection.value.maxRetries}次，请检查服务器状态`,
              duration: 5000,
            });
            // 清理连接状态
            // cleanupConnection();
          } else {
            ElMessage.warning("设备连接已断开");
          }
        }
      });
    }

    // 创建录音器
    if (!pcmRecorder) {
      pcmRecorder = new (window as any).PcmRecorder();
      await pcmRecorder.requestMicrophone();

      // 等待麦克风准备就绪
      await new Promise<void>((resolve, reject) => {
        const checkReady = setInterval(() => {
          if (pcmRecorder.ready) {
            clearInterval(checkReady);
            resolve();
          }
        }, 100);

        // 5秒超时
        setTimeout(() => {
          clearInterval(checkReady);
          if (!pcmRecorder.ready) {
            reject(new Error("麦克风初始化超时"));
          }
        }, 5000);
      });

      pcmRecorder.onFrameData = parrotClient.sendFrame.bind(parrotClient);

      parrotClient.on("startRecord", pcmRecorder.startRecord.bind(pcmRecorder));
      parrotClient.on("stopRecord", pcmRecorder.stopRecord.bind(pcmRecorder));
    }

    return true;
  } catch (error) {
    console.error("初始化Parrot客户端失败:", error);
    ElMessage.error("初始化失败: " + error);
    return false;
  }
};

// 创建连接
const startShout = async () => {
  // 验证是否选择了设备
  if (selectedDevices.value.length === 0) {
    ElMessage.warning("请先选择设备");
    return;
  }

  // 如果当前已连接，需要先断开连接
  if (callStatus.value.isConnected) {
    await cleanupConnection();
    ElMessage.info("设备已重新选择，正在重新建立连接");
  }

  const loadingInstance = ElLoading.service({
    lock: true,
    text: "正在获取连接参数...",
    background: "rgba(0, 0, 0, 0.7)",
  });

  try {
    // 1. 获取广播服务器列表
    const serverResponse = await getBroadcastServerList();
    if (serverResponse.code !== ResultCode.SUCCESS) {
      throw new Error(serverResponse.message || "获取广播服务器列表失败");
    }

    const serverList = serverResponse.data.list as BroadcastServer[];
    if (!serverList || serverList.length === 0) {
      throw new Error("未找到可用的广播服务器");
    }

    // 2. 按服务器分组设备
    const selectedDeviceInfos = getSelectedDevicesInfo();
    const devicesByServer = new Map<number, DeviceItem[]>();

    selectedDeviceInfos.forEach(device => {
      if (!devicesByServer.has(device.serverId)) {
        devicesByServer.set(device.serverId, []);
      }
      devicesByServer.get(device.serverId)!.push(device);
    });

    // 3. 为每个服务器创建连接
    loadingInstance.setText("正在建立连接...");
    const serverMap = new Map(serverList.map(s => [s.id, s]));

    for (const [serverId, devices] of devicesByServer.entries()) {
      const serverInfo = serverMap.get(serverId);
      if (!serverInfo) {
        console.warn(`未找到服务器${serverId}的配置`);
        continue;
      }

      try {
        // 初始化服务器的Parrot客户端
        const clientInfo = await initServerParrotClient(
          serverId,
          serverInfo,
          devices.map(d => d.deviceId) // 使用 deviceId
        );

        if (!clientInfo) {
          throw new Error("客户端初始化失败");
        }

        // 创建服务器连接对象
        const serverConn: ServerConnection = {
          server: serverInfo,
          connected: false,
          connecting: true,
          parrotClient: clientInfo.parrotClient,
          pcmPlayer: clientInfo.pcmPlayer,
          connectionParams: clientInfo.connectionParams,
          devices: devices.map(d => d.deviceId), // 使用 deviceId
          retryCount: 0,
          maxRetries: 3, // 最大重连3次
          lastRetryTime: 0,
          connectionFailed: false
        };

        serverConnections.value.set(serverId, serverConn);

        // 建立WebSocket连接
        await connectServerWebSocket(serverId);

      } catch (error) {
        console.error(`服务器${serverId}连接失败:`, error);
        ElMessage.warning(`服务器${serverId}连接失败: ${error}`);
      }
    }

    // 检查是否有成功连接的服务器
    const anyConnected = Array.from(serverConnections.value.values()).some(
      conn => conn.connected
    );

    if (!anyConnected) {
      throw new Error("所有服务器连接失败");
    }

    loadingInstance.close();
    ElMessage.success("连接建立成功，可以开始说话");
  } catch (error: any) {
    loadingInstance.close();
    ElMessage.error(error.message || "建立连接失败");
    callStatus.value.isConnected = false;
  }
};

// 连接单个服务器的WebSocket
const connectServerWebSocket = async (serverId: number) => {
  return new Promise((resolve, reject) => {
    const conn = serverConnections.value.get(serverId);
    if (!conn) {
      reject(new Error("服务器连接未初始化"));
      return;
    }

    // 检查连接是否已经失败，如果失败则不再尝试连接
    if (conn.connectionFailed) {
      reject(new Error("服务器连接已失败，不再尝试连接"));
      return;
    }

    try {
      const client = conn.parrotClient;
      const params = conn.connectionParams;

      // 设置连接参数
      client.setLogLevel(0);
      client.setUsername(params.user);
      client.setTimestamp("1649209905");
      client.setPassword(params.pwd);
      client.setUrl(params.ws_url);

      // 打开连接
      client.openParrot();

      // 监听连接状态，等待连接成功
      const checkConnection = setInterval(() => {
        if (conn.connected) {
          clearInterval(checkConnection);
          resolve(true);
        }
      }, 100);

      // 30秒超时
      setTimeout(() => {
        clearInterval(checkConnection);
        if (!conn.connected) {
          reject(new Error("连接超时"));
        }
      }, 30000);
    } catch (error) {
      reject(error);
    }
  });
};

// 连接WebSocket(保留旧版本以兼容)
const connectWebSocket = async () => {
  return new Promise((resolve, reject) => {
    if (!parrotClient) {
      reject(new Error("客户端未初始化"));
      return;
    }

    try {
      // 设置连接参数
      parrotClient.setLogLevel(0);
      parrotClient.setUsername(wsConnection.value.user);
      parrotClient.setTimestamp("1649209905");
      parrotClient.setPassword(wsConnection.value.password);
      parrotClient.setUrl(wsConnection.value.wsUrl);

      // 打开连接
      parrotClient.openParrot();

      // 监听连接状态，等待连接成功
      const checkConnection = setInterval(() => {
        if (wsConnection.value.connected) {
          clearInterval(checkConnection);
          resolve(true);
        }
      }, 100);

      // 30秒超时（因为可能有多次重试）
      setTimeout(() => {
        clearInterval(checkConnection);
        if (!wsConnection.value.connected) {
          reject(new Error("连接超时"));
        }
      }, 30000);
    } catch (error) {
      reject(error);
    }
  });
};

// 开始说话（只发送设备确认消息）
const startSpeaking = async () => {
  if (!callStatus.value.isConnected) {
    ElMessage.error("连接未建立，请先创建连接");
    return;
  }

  const deviceIds = selectedDevices.value;
  if (deviceIds.length === 0) {
    ElMessage.warning("请先选择设备");
    return;
  }

  callStatus.value.loading = true;
  callStatus.value.deviceStatus = {};

  try {
    // 按服务器分组设备
    const selectedDeviceInfos = getSelectedDevicesInfo();
    const devicesByServer = new Map<number, number[]>();
    
    selectedDeviceInfos.forEach(device => {
      if (!devicesByServer.has(device.serverId)) {
        devicesByServer.set(device.serverId, []);
      }
      devicesByServer.get(device.serverId)!.push(device.deviceId); // 使用 deviceId
    });

    // 向每个服务器发送喊话命令
    for (const [serverId, deviceList] of devicesByServer.entries()) {
      const conn = serverConnections.value.get(serverId);
      if (conn && conn.connected && conn.parrotClient) {
        try {
          conn.parrotClient.startLiveCast(deviceList);
        } catch (error) {
          console.error(`服务器${serverId}开始喊话失败:`, error);
        }
      }
    }

    callStatus.value.isSpeaking = true;
    callStatus.value.loading = false;
    callStatus.value.speakStartTime = Math.floor(Date.now() / 1000); // 记录开始时间（秒）
    ElMessage.success(`已向${deviceIds.length}台设备发送确认消息`);

    // 延迟检查设备连接状态
    setTimeout(() => {
      const connectedDevices = Object.values(
        callStatus.value.deviceStatus
      ).filter(Boolean).length;
      const totalDevices = deviceIds.length;

      if (connectedDevices === totalDevices) {
        ElMessage.success(`所有设备(${totalDevices}台)连接成功`);
      } else if (connectedDevices > 0) {
        ElMessage.warning(`${connectedDevices}/${totalDevices}台设备连接成功`);
      }
    }, 2000);
  } catch (error: any) {
    callStatus.value.loading = false;
    ElMessage.error(error.message || "发送设备确认消息失败");
  }
};

// 停止说话
const stopSpeaking = async () => {
  // 向所有服务器发送停止命令
  for (const conn of serverConnections.value.values()) {
    if (conn.parrotClient) {
      try {
        conn.parrotClient.stopLiveCast();
      } catch (error) {
        console.error("停止说话失败:", error);
      }
    }
  }

  // 兼容旧版本
  if (parrotClient) {
    try {
      parrotClient.stopLiveCast();
    } catch (error) {
      console.error("停止说话失败:", error);
    }
  }

  // 如果有开始时间，则创建广播记录
  if (callStatus.value.speakStartTime !== null) {
    try {
      const endTime = Math.floor(Date.now() / 1000);
      const selectedDeviceInfos = getSelectedDevicesInfo();
      const deviceIds = selectedDeviceInfos.map(d => d.deviceId);

      if (deviceIds.length > 0) {
        await createBroadcastRecord({
          type: 2, // 喊话类型
          device: deviceIds,
          start_time: callStatus.value.speakStartTime,
          end_time: endTime
        });
        console.log('喊话记录创建成功');
      }
    } catch (error) {
      console.error('创建喊话记录失败:', error);
    }
  }

  callStatus.value.isSpeaking = false;
  callStatus.value.loading = false;
  callStatus.value.speakStartTime = null; // 清空开始时间
};

// 清理连接状态
const cleanupConnection = async () => {
  // 如果有开始时间，先创建广播记录
  if (callStatus.value.speakStartTime !== null) {
    try {
      const endTime = Math.floor(Date.now() / 1000);
      const selectedDeviceInfos = getSelectedDevicesInfo();
      const deviceIds = selectedDeviceInfos.map(d => d.deviceId);

      if (deviceIds.length > 0) {
        await createBroadcastRecord({
          type: 2, // 喊话类型
          device: deviceIds,
          start_time: callStatus.value.speakStartTime,
          end_time: endTime
        });
        console.log('断开连接时创建喊话记录成功');
      }
    } catch (error) {
      console.error('断开连接时创建喊话记录失败:', error);
    }
  }

  // 清理所有服务器连接
  for (const conn of serverConnections.value.values()) {
    if (conn.parrotClient) {
      try {
        conn.parrotClient.stopLiveCast();
        conn.parrotClient.closeParrot();
      } catch (error) {
        console.error("清理服务器连接失败:", error);
      }
    }
  }
  serverConnections.value.clear();

  // 清理共享的录音器
  if (sharedPcmRecorder) {
    try {
      if (sharedPcmRecorder.isRecording) {
        sharedPcmRecorder.stopRecord();
      }
      sharedPcmRecorder.frameCallbacks = [];
      sharedPcmRecorder = null;
    } catch (error) {
      console.error("清理共享录音器失败:", error);
    }
  }

  // 兼容旧版本
  if (parrotClient) {
    try {
      parrotClient.stopLiveCast();
      parrotClient.closeParrot();
    } catch (error) {
      console.error("清理连接失败:", error);
    }
  }

  callStatus.value.isSpeaking = false;
  callStatus.value.isConnected = false;
  callStatus.value.loading = false;
  callStatus.value.deviceStatus = {};
  callStatus.value.serverStatus = {};
  callStatus.value.speakStartTime = null; // 清空开始时间
  wsConnection.value.connected = false;
  wsConnection.value.connecting = false;
  wsConnection.value.retryCount = 0;
  broadcastServer.value = null;
};

// 停止喊话
const stopShout = async () => {
  await cleanupConnection();
  ElMessage.info("已停止喊话");
};

// 设备变更时重新发送确认消息
const updateDeviceTargets = async () => {
  if (!parrotClient || !wsConnection.value.connected) {
    return;
  }

  const deviceIds = selectedDevices.value;
  if (deviceIds.length === 0) {
    return;
  }

  try {
    // 重新发送设备确认消息
    parrotClient.startLiveCast(deviceIds);
    ElMessage.info(`已更新目标设备，向${deviceIds.length}台设备发送确认消息`);

    // 清空设备状态
    callStatus.value.deviceStatus = {};

    // 延迟检查设备连接状态
    setTimeout(() => {
      const connectedDevices = Object.values(
        callStatus.value.deviceStatus
      ).filter(Boolean).length;
      const totalDevices = deviceIds.length;

      if (connectedDevices === totalDevices) {
        ElMessage.success(`所有设备(${totalDevices}台)连接成功`);
      } else if (connectedDevices > 0) {
        ElMessage.warning(`${connectedDevices}/${totalDevices}台设备连接成功`);
      }
    }, 2000);
  } catch (error: any) {
    ElMessage.error("更新设备目标失败");
  }
};

// 打开设备选择弹窗
const openDeviceDialog = async () => {
  showDeviceDialog.value = true;

  // 每次点击都重新获取树数据
  await loadTreeData();

  // 将当前选中的设备同步到临时选择中
  tempSelectedDevices.value = [...selectedDevices.value];
};

// 监听弹窗打开，同步临时选择状态
watch(showDeviceDialog, (newVal) => {
  if (newVal) {
    // 打开弹窗时，将当前选中的设备同步到临时选择中
    tempSelectedDevices.value = [...selectedDevices.value];
  }
});

// 加载设备树数据
const loadTreeData = async () => {
  try {
    const response = await tree();
    if (response.code === ResultCode.SUCCESS && response.data) {
      treeData.value = response.data;

      // 初始化大区列表
      regionList.value = response.data.map((r) => ({ id: r.id, name: r.name }));

      // 自动加载所有设备
      deviceList.value = collectAllDevices(response.data);
    } else {
      ElMessage.error(response.message || "获取设备树失败");
    }
  } catch (error) {
    console.error("加载设备树失败:", error);
    ElMessage.error("加载设备树失败，请刷新重试");
  }
};

// 页面加载时初始化
onMounted(async () => {
  // 加载必要的JS文件
  const scriptBasePath = "/parrot/";

  try {
    // 按顺序加载JS文件
    await loadScript(scriptBasePath + "parrotapi-es5.js");
    await loadScript(scriptBasePath + "PcmPlayer.js");
    await loadScript(scriptBasePath + "PcmRecorder.js");
    await loadScript(scriptBasePath + "ParrotClient.js");

    // 等待一小段时间确保脚本完全执行
    await new Promise((resolve) => setTimeout(resolve, 100));

    // 初始化ParrotApi
    if (typeof (window as any).ParrotApi === "function") {
      parrotApi = await (window as any).ParrotApi();

      // 确保 ParrotApi 对象完全初始化
      if (!parrotApi) {
        throw new Error("ParrotApi 初始化失败");
      }
    } else {
      ElMessage.error("ParrotApi 加载失败");
    }
  } catch (error) {
    console.error("初始化失败:", error);
    ElMessage.error("初始化失败，请刷新页面重试");
  }
});

// 组件卸载时清理资源
onBeforeUnmount(() => {
  cleanupConnection();

  // 停止录音
  if (pcmRecorder && pcmRecorder.__audio_context) {
    pcmRecorder.stopRecord();
  }

  // 销毁播放器
  if (pcmPlayer) {
    pcmPlayer.destroy();
  }

  // 清空引用
  parrotClient = null;
  pcmPlayer = null;
  pcmRecorder = null;
});
</script>

<style scoped lang="scss">
.broadcast-shout-page {
  padding: 20px;
  margin: 0 auto;

  .page-header {
    text-align: center;
    margin-bottom: 30px;
    padding: 20px;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    border-radius: 12px;
    color: white;

    .page-title {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 10px;
      margin: 0 0 10px 0;
      font-size: 24px;
      font-weight: 600;
    }

    .page-description {
      margin: 0;
      font-size: 14px;
      opacity: 0.9;
    }
  }

  .section-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 20px 0 15px 0;
    font-size: 16px;
    font-weight: 600;
    color: #303133;
  }

  // 主页设备选择卡片
  .device-selection-card {
    margin-bottom: 30px;
    padding: 24px;
    background-color: #fff;
    border-radius: 12px;
    border: 1px solid #e4e7ed;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 20px;
      padding-bottom: 16px;
      border-bottom: 2px solid #f0f0f0;
    }

    .empty-device {
      padding: 40px 20px;
      text-align: center;
    }

    .selected-devices-list {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;
      min-height: 60px;

      .device-tag {
        padding: 8px 16px;
        font-size: 14px;

        .tag-content {
          display: flex;
          flex-direction: column;
          gap: 4px;

          .device-name {
            font-weight: 600;
          }

          .device-id {
            font-size: 12px;
            opacity: 0.8;
          }
        }
      }
    }
  }

  .call-control {
    .control-buttons {
      display: flex;
      gap: 20px;
      justify-content: center;
      margin: 20px 0;

      .control-btn {
        min-width: 150px;
        height: 50px;
        font-size: 16px;
      }
    }

    .call-status {
      text-align: center;
      margin-top: 20px;
    }
  }

  .action-buttons {
    display: flex;
    gap: 20px;
    justify-content: center;
    margin-top: 30px;
    padding-top: 20px;
    border-top: 1px solid #e4e7ed;

    .action-btn {
      min-width: 150px;
      height: 45px;
      font-size: 16px;
    }
  }
}

// 响应式设计
@media (max-width: 768px) {
  .broadcast-shout-page {
    padding: 15px;

    .hierarchical-filters {
      .filter-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;

        .filter-item {
          width: 100%;
          justify-content: space-between;

          label {
            min-width: 80px;
          }
        }
      }
    }

    .device-list {
      height: calc(100vh - 400px);
      min-height: 250px;
      max-height: 500px;
    }

    .device-cards {
      grid-template-columns: 1fr;
    }

    .device-header {
      flex-direction: column;
      align-items: flex-start;
      gap: 10px;

      .device-actions {
        width: 100%;
        justify-content: center;
      }
    }

    .control-buttons,
    .action-buttons {
      flex-direction: column;
      align-items: center;

      .control-btn,
      .action-btn {
        width: 100%;
        max-width: 300px;
      }
    }
  }
}
</style>

<!-- 弹窗全局样式 -->
<style>
.device-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-right: 20px;

  .device-actions {
    display: flex;
    gap: 10px;
  }
}
.device-dialog .el-dialog__body {
  max-height: 70vh;
  overflow-y: auto;
}

.device-dialog .hierarchical-filters {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e4e7ed;
}

.device-dialog .hierarchical-filters .section-title {
  margin: 0 0 15px 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  display: flex;
  align-items: center;
  gap: 8px;
}

.device-dialog .hierarchical-filters .filter-container {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
}

.device-dialog .hierarchical-filters .filter-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.device-dialog .hierarchical-filters .filter-item label {
  font-weight: 500;
  color: #606266;
  white-space: nowrap;
}

.device-dialog .hierarchical-filters .filter-item .el-select {
  min-width: 150px;
}

.device-dialog .device-list {
  height: 400px;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  padding: 10px;
}

.device-dialog .device-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
  /* height: 100%; */
  overflow-y: auto;
}

.device-dialog .empty-state {
  text-align: center;
  padding: 40px;
  color: #909399;
}

.device-dialog .device-list .device-card {
  display: flex;
  flex-direction: column;
  padding: 4px 6px;
  margin-bottom: 4px;
  background-color: #fff;
  border: 1px solid #e4e7ed;
  border-radius: 3px;
  cursor: pointer;
  height: auto;
  min-height: 60px;
}

.device-dialog .device-list .device-card.selected {
  border-color: #409eff;
  background-color: #f0f9ff;
}

.device-dialog .device-list .device-card.offline {
  opacity: 0.6;
  background-color: #f5f5f5;
}

.device-dialog .device-list .device-card .card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1px;
}

.device-dialog .device-list .device-card .device-name {
  font-weight: 500;
  color: #303133;
  font-size: 11px;
  margin-bottom: 1px;
  line-height: 1.1;
}

.device-dialog .device-list .device-card .device-details {
  font-size: 9px;
  color: #909399;
  line-height: 1.1;
  margin-bottom: 1px;
}

.device-dialog .device-list .device-card .device-status {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-top: 1px;
}

.device-dialog .device-list .device-card .status-indicator {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background-color: #67c23a;
}

.device-dialog .device-list .device-card .status-indicator.offline {
  background-color: #f56c6c;
}

.device-dialog .device-list .device-card .status-text {
  font-size: 9px;
  color: #606266;
  font-weight: 400;
}
</style>
